package com.cook.controller;

import com.cook.dto.recipes.TagsDTO;
import com.cook.result.Result;
import com.cook.service.TagsService;
import com.cook.vo.recipes.TagsVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/tags")
@Slf4j
public class TagsController {

    @Autowired
    private TagsService tagsService;

    /**
     * 分页查询标签列表
     */
    @GetMapping
    public Result<Map<String, Object>> getTagsWithPage(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "20") Integer pageSize) {

        log.info("分页查询标签列表: pageNum={}, pageSize={}", pageNum, pageSize);

        try {
            Map<String, Object> result = tagsService.getTagsWithPage(pageNum, pageSize);
            return Result.success(result);
        } catch (IllegalArgumentException e) {
            log.warn("参数错误: {}", e.getMessage());
            return Result.error(400, e.getMessage());
        } catch (Exception e) {
            log.error("查询标签列表失败: ", e);
            return Result.error(500, "查询标签列表失败");
        }
    }

    /**
     * 查询所有标签列表
     */
    @GetMapping("/allTags")
    public Result<Map<String, Object>> getTags() {
        log.info("查询所有标签列表");

        try {
            Map<String, Object> result = tagsService.getTags();
            return Result.success(result);
        } catch (IllegalArgumentException e) {
            log.warn("参数错误: {}", e.getMessage());
            return Result.error(400, e.getMessage());
        } catch (Exception e) {
            log.error("查询标签列表失败: ", e);
            return Result.error(500, "查询标签列表失败");
        }
    }

    /**
     * 根据类型查询标签
     */
    @GetMapping("/type/{type}")
    public Result<Map<String, Object>> getTagsByType(
            @PathVariable String type,
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "20") Integer pageSize) {

        log.info("根据类型查询标签: type={}, pageNum={}, pageSize={}", type, pageNum, pageSize);

        try {
            Map<String, Object> result = tagsService.getTagsByType(type, pageNum, pageSize);
            return Result.success(result);
        } catch (IllegalArgumentException e) {
            log.warn("参数错误: {}", e.getMessage());
            return Result.error(400, e.getMessage());
        } catch (Exception e) {
            log.error("根据类型查询标签失败: ", e);
            return Result.error(500, "查询标签失败");
        }
    }

    /**
     * 根据标签查询菜谱
     */
    @GetMapping("/{tagId}/recipes")
    public Result<Map<String, Object>> getRecipesByTagId(
            @PathVariable Long tagId,
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize) {

        log.info("根据标签查询菜谱: tagId={}, pageNum={}, pageSize={}", tagId, pageNum, pageSize);

        try {
            Map<String, Object> result = tagsService.getRecipesByTagId(tagId, pageNum, pageSize);
            return Result.success(result);
        } catch (IllegalArgumentException e) {
            log.warn("参数错误: {}", e.getMessage());
            return Result.error(400, e.getMessage());
        } catch (Exception e) {
            log.error("根据标签查询菜谱失败: ", e);
            return Result.error(500, "查询菜谱失败");
        }
    }

    /**
     * 查询菜谱的所有标签
     */
    @GetMapping("/recipe/{recipeId}")
    public Result<List<TagsVO>> getTagsByRecipeId(@PathVariable Long recipeId) {
        log.info("查询菜谱的标签: recipeId={}", recipeId);

        try {
            List<TagsVO> tagsList = tagsService.getTagsByRecipeId(recipeId);
            return Result.success(tagsList);
        } catch (IllegalArgumentException e) {
            log.warn("参数错误: {}", e.getMessage());
            return Result.error(400, e.getMessage());
        } catch (Exception e) {
            log.error("查询菜谱标签失败: ", e);
            return Result.error(500, "查询标签失败");
        }
    }

    /**
     * 添加新标签
     */
    @PostMapping
    public Result<Long> addTag(@RequestBody TagsDTO tagsDTO) {
        log.info("添加标签: name={}, type={}", tagsDTO.getName(), tagsDTO.getType());

        try {
            Long tagId = tagsService.addTag(tagsDTO);
            return Result.success("标签添加成功", tagId);
        } catch (IllegalArgumentException e) {
            log.warn("参数错误: {}", e.getMessage());
            return Result.error(400, e.getMessage());
        } catch (RuntimeException e) {
            log.warn("添加标签失败: {}", e.getMessage());
            return Result.error(409, e.getMessage()); // 409 Conflict
        } catch (Exception e) {
            log.error("添加标签失败: ", e);
            return Result.error(500, "添加标签失败");
        }
    }

    /**
     * 为菜谱添加标签
     */
    @PostMapping("/recipe/{recipeId}/tag/{tagId}")
    public Result<Boolean> addRecipeTag(
            @PathVariable Long recipeId,
            @PathVariable Long tagId) {

        log.info("为菜谱添加标签: recipeId={}, tagId={}", recipeId, tagId);

        try {
            boolean success = tagsService.addRecipeTag(recipeId, tagId);
            if (success) {
                return Result.success("标签添加成功", true);
            } else {
                return Result.error(500, "添加标签失败");
            }
        } catch (IllegalArgumentException e) {
            log.warn("参数错误: {}", e.getMessage());
            return Result.error(400, e.getMessage());
        } catch (RuntimeException e) {
            log.warn("添加标签失败: {}", e.getMessage());
            return Result.error(409, e.getMessage());
        } catch (Exception e) {
            log.error("添加标签失败: ", e);
            return Result.error(500, "添加标签失败");
        }
    }

    /**
     * 删除标签
     */
    @DeleteMapping("/{tagId}")
    public Result<Boolean> deleteTag(@PathVariable Long tagId) {
        log.info("删除标签: tagId={}", tagId);

        try {
            boolean success = tagsService.deleteTag(tagId);
            if (success) {
                return Result.success("标签删除成功", true);
            } else {
                return Result.error(500, "删除标签失败");
            }
        } catch (IllegalArgumentException e) {
            log.warn("参数错误: {}", e.getMessage());
            return Result.error(400, e.getMessage());
        } catch (Exception e) {
            log.error("删除标签失败: ", e);
            return Result.error(500, "删除标签失败");
        }
    }

    /**
     * 删除菜谱的标签
     */
    @DeleteMapping("/recipe/{recipeId}/tag/{tagId}")
    public Result<Boolean> deleteRecipeTag(
            @PathVariable Long recipeId,
            @PathVariable Long tagId) {

        log.info("删除菜谱标签: recipeId={}, tagId={}", recipeId, tagId);

        try {
            boolean success = tagsService.deleteRecipeTag(recipeId, tagId);
            if (success) {
                return Result.success("标签删除成功", true);
            } else {
                return Result.error(500, "删除标签失败");
            }
        } catch (IllegalArgumentException e) {
            log.warn("参数错误: {}", e.getMessage());
            return Result.error(400, e.getMessage());
        } catch (Exception e) {
            log.error("删除标签失败: ", e);
            return Result.error(500, "删除标签失败");
        }
    }

    /**
     * 统计所有标签名称的数量
     */
    @GetMapping("/stats/name-count")
    public Result<List<Map<String, Object>>> countTagsByName() {
        log.info("统计标签名称数量");

        try {
            List<Map<String, Object>> result = tagsService.countTagsByName();
            return Result.success(result);
        } catch (Exception e) {
            log.error("统计标签名称数量失败: ", e);
            return Result.error(500, "统计标签名称失败");
        }
    }

    /**
     * 根据类型统计标签名称的数量
     */
    @GetMapping("/stats/name-count/{type}")
    public Result<List<Map<String, Object>>> countTagsByNameAndType(@PathVariable String type) {
        log.info("根据类型统计标签名称数量: type={}", type);

        try {
            List<Map<String, Object>> result = tagsService.countTagsByNameAndType(type);
            return Result.success(result);
        } catch (IllegalArgumentException e) {
            log.warn("参数错误: {}", e.getMessage());
            return Result.error(400, e.getMessage());
        } catch (Exception e) {
            log.error("根据类型统计标签名称数量失败: ", e);
            return Result.error(500, "统计标签名称失败");
        }
    }

    /**
     * 根据标签名称搜索标签
     */
    @GetMapping("/search")
    public Result<List<TagsVO>> searchTagsByName(@RequestParam String keyword) {
        log.info("搜索标签: keyword={}", keyword);

        if (keyword == null || keyword.trim().isEmpty()) {
            return Result.error(400, "搜索关键词不能为空");
        }

        try {
            // 这里可以调用Service层的方法进行搜索
            // 由于Service层没有实现搜索功能，这里可以直接调用Mapper
            // 实际项目中应该在Service层实现
            return Result.success("搜索功能待实现", null);
        } catch (Exception e) {
            log.error("搜索标签失败: ", e);
            return Result.error(500, "搜索标签失败");
        }
    }

    /**
     * 批量添加菜谱标签
     */
    //TODO 暂时打算一个一个添加标签
//    @PostMapping("/recipe/{recipeId}/batch")
//    public Result<Boolean> addRecipeTagsBatch(
//            @PathVariable Long recipeId,
//            @RequestBody List<Long> tagIds) {
//
//        log.info("批量添加菜谱标签: recipeId={}, tagIds={}", recipeId, tagIds);
//
//        if (tagIds == null || tagIds.isEmpty()) {
//            return Result.error(400, "标签ID列表不能为空");
//        }
//
//        try {
//            int successCount = 0;
//            for (Long tagId : tagIds) {
//                try {
//                    boolean success = tagsService.addRecipeTag(recipeId, tagId);
//                    if (success) successCount++;
//                } catch (Exception e) {
//                    log.warn("添加标签失败: recipeId={}, tagId={}", recipeId, tagId, e);
//                }
//            }
//
//            if (successCount > 0) {
//                return Result.success(String.format("成功添加 %d 个标签", successCount), true);
//            } else {
//                return Result.error("添加标签失败");
//            }
//        } catch (Exception e) {
//            log.error("批量添加标签失败: ", e);
//            return Result.error(500, "批量添加标签失败");
//        }
//    }
}